package com.ruoyi.system.service.impl;

import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.AlpContractDetail;
import com.ruoyi.system.domain.PivotRequest;
import com.ruoyi.system.mapper.AlpContractDetailMapper;
import com.ruoyi.system.mapper.AlpWeeklyMapper;
import com.ruoyi.system.service.IAlpWeeklyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @fileName: AlpWeeklyServiceImpl
 * @description: TODO
 * @author: Li Wenbo
 * @date: 2020-3-2 14:47
 * @version: V1.0
 */
@Service
public class AlpWeeklyServiceImpl implements IAlpWeeklyService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AlpWeeklyServiceImpl.class);

    @Autowired
    private AlpWeeklyMapper alpWeeklyMapper;
    @Autowired
    private AlpContractDetailMapper alpContractDetailMapper;


    @Override
    public List<Map> getTotalWeeklyList() {
        List<Map> list = alpWeeklyMapper.getTotalWeeklyList();
        Map budgetMap = new HashMap<>();
        budgetMap.put("type","预算");
        Map predictMap = new HashMap<>();
        predictMap.put("type","预测");
        Map actualMap = new HashMap<>();
        actualMap.put("type","结果");
        Map budgetPercentMap = new HashMap<>();
        budgetPercentMap.put("type","预算准确度");
        Map predictPercentMap = new HashMap<>();
        predictPercentMap.put("type","预测准确度");
        //2020-3-13添加，每类统计都添加合计列
        BigDecimal totalBudget = new BigDecimal(0);
        BigDecimal totalPredict = new BigDecimal(0);
        BigDecimal totalActual = new BigDecimal(0);
        DecimalFormat df = new DecimalFormat("0.00%");
        for(int i = 0; i <= list.size(); i++) {
            if (i < list.size()) {
                Map map = list.get(i);
                //计算预测准确率
                BigDecimal bMoney = (BigDecimal) map.get("budget_money");
                BigDecimal pMoney = (BigDecimal) map.get("predict_money");
                BigDecimal aMoney = (BigDecimal) map.get("actual_money");
                String budgetPercent;
                String predictPercent;
                if (bMoney.compareTo(BigDecimal.ZERO) == 0) {
                    budgetPercent = "0.00%";
                } else {
                    BigDecimal budgetPercentResult = aMoney.divide(bMoney, 4, BigDecimal.ROUND_HALF_UP);
                    budgetPercent = df.format(budgetPercentResult);
                }
                if (pMoney.compareTo(BigDecimal.ZERO) == 0) {
                    predictPercent = "0.00%";
                } else {
                    BigDecimal predictPercentResult = aMoney.divide(pMoney, 4, BigDecimal.ROUND_HALF_UP);
                    predictPercent = df.format(predictPercentResult);
                }
                budgetMap.put(String.valueOf(i + 1), map.get("budget_money"));
                predictMap.put(String.valueOf(i + 1), map.get("predict_money"));
                actualMap.put(String.valueOf(i + 1), map.get("actual_money"));
                budgetPercentMap.put(String.valueOf(i + 1), budgetPercent);
                predictPercentMap.put(String.valueOf(i + 1), predictPercent);
                //2020-3-13新加合计模块
                totalBudget = totalBudget.add(bMoney);
                totalActual = totalActual.add(aMoney);
                int week = DateUtils.getWeekOfYearByF(new Date(),5);
                if (i < week - 1) {
                    totalPredict = totalPredict.add(aMoney);
                } else {
                    totalPredict = totalPredict.add(pMoney);
                }
            } else {
                budgetMap.put(String.valueOf(i + 1), totalBudget);
                predictMap.put(String.valueOf(i + 1), totalPredict);
                actualMap.put(String.valueOf(i + 1), totalActual);
                if (totalBudget.compareTo(BigDecimal.ZERO) == 0) {
                    budgetPercentMap.put(String.valueOf(i + 1), "0.00%");
                } else {
                    BigDecimal budgetPercentResult = totalActual.divide(totalBudget, 4, BigDecimal.ROUND_HALF_UP);
                    budgetPercentMap.put(String.valueOf(i + 1), df.format(budgetPercentResult));
                }
                if (totalPredict.compareTo(BigDecimal.ZERO) == 0) {
                    predictPercentMap.put(String.valueOf(i + 1), "0.00%");
                } else {
                    BigDecimal predictPercentResult = totalActual.divide(totalPredict, 4, BigDecimal.ROUND_HALF_UP);
                    predictPercentMap.put(String.valueOf(i + 1), df.format(predictPercentResult));
                }
            }
            //合计end
        }
        List<Map> resultList = new ArrayList<>();
        resultList.add(budgetMap);
        resultList.add(predictMap);
        resultList.add(actualMap);
        resultList.add(budgetPercentMap);
        resultList.add(predictPercentMap);
        return resultList;
    }

    @Override
    public List<Map> getDeptWeeklyList(String deptNames) {
        List<String> nameList = new ArrayList<>();
        List<Map> resultList = new ArrayList<>();
        List<String> nameListFromDB = alpWeeklyMapper.getAllDeptName();
        if(StringUtils.isNotEmpty(deptNames)) {
            String[] personNameList = deptNames.split(",");
            for (String pn : personNameList) {
                List searchedList = CollectionUtils.search(pn, nameListFromDB);
                nameList.addAll(searchedList);
            }
        }
        if(nameList.size() > 0){
            for(String name: nameList){
                List<Map> list = alpWeeklyMapper.getDeptWeeklyList(name);
                Map budgetMap = new HashMap<>();
                budgetMap.put("type","预算");
                budgetMap.put("name",name);
                Map predictMap = new HashMap<>();
                predictMap.put("type","预测");
                predictMap.put("name",name);
                Map actualMap = new HashMap<>();
                actualMap.put("type","结果");
                actualMap.put("name",name);
                Map budgetPercentMap = new HashMap<>();
                budgetPercentMap.put("type","预算准确度");
                budgetPercentMap.put("name",name);
                Map predictPercentMap = new HashMap<>();
                predictPercentMap.put("type","预测准确度");
                predictPercentMap.put("name",name);
                //2020-3-13添加，每类统计都添加合计列
                BigDecimal totalBudget = new BigDecimal(0);
                BigDecimal totalPredict = new BigDecimal(0);
                BigDecimal totalActual = new BigDecimal(0);
                DecimalFormat df = new DecimalFormat("0.00%");
                for(int i = 0; i <= list.size(); i++) {
                    if (i < list.size()) {
                        Map map = list.get(i);
                        //计算预测准确率
                        BigDecimal bMoney = (BigDecimal)map.get("budget_money");
                        BigDecimal pMoney = (BigDecimal)map.get("predict_money");
                        BigDecimal aMoney = (BigDecimal)map.get("actual_money");
                        String budgetPercent;
                        String predictPercent;
                        if(bMoney.compareTo(BigDecimal.ZERO) == 0) {
                            budgetPercent = "0.00%";
                        } else {
                            BigDecimal budgetPercentResult = aMoney.divide(bMoney,4,BigDecimal.ROUND_HALF_UP);
                            budgetPercent = df.format(budgetPercentResult);
                        }
                        if(pMoney.compareTo(BigDecimal.ZERO) == 0) {
                            predictPercent = "0.00%";
                        } else {
                            BigDecimal predictPercentResult = aMoney.divide(pMoney,4,BigDecimal.ROUND_HALF_UP);
                            predictPercent = df.format(predictPercentResult);
                        }
                        budgetMap.put(String.valueOf(i+1), map.get("budget_money"));
                        predictMap.put(String.valueOf(i+1), map.get("predict_money"));
                        actualMap.put(String.valueOf(i+1), map.get("actual_money"));
                        budgetPercentMap.put(String.valueOf(i+1), budgetPercent);
                        predictPercentMap.put(String.valueOf(i+1), predictPercent);
                        //2020-3-13新加合计模块
                        totalBudget = totalBudget.add(bMoney);
                        totalActual = totalActual.add(aMoney);
                        int week = DateUtils.getWeekOfYearByF(new Date(),5);
                        if (i < week - 1) {
                            totalPredict = totalPredict.add(aMoney);
                        }else{
                            totalPredict = totalPredict.add(pMoney);
                        }
                    } else {
                        budgetMap.put(String.valueOf(i + 1), totalBudget);
                        predictMap.put(String.valueOf(i + 1), totalPredict);
                        actualMap.put(String.valueOf(i + 1), totalActual);
                        if (totalBudget.compareTo(BigDecimal.ZERO) == 0) {
                            budgetPercentMap.put(String.valueOf(i + 1), "0.00%");
                        } else {
                            BigDecimal budgetPercentResult = totalActual.divide(totalBudget, 4, BigDecimal.ROUND_HALF_UP);
                            budgetPercentMap.put(String.valueOf(i + 1), df.format(budgetPercentResult));
                        }
                        if (totalPredict.compareTo(BigDecimal.ZERO) == 0) {
                            predictPercentMap.put(String.valueOf(i + 1), "0.00%");
                        } else {
                            BigDecimal predictPercentResult = totalActual.divide(totalPredict, 4, BigDecimal.ROUND_HALF_UP);
                            predictPercentMap.put(String.valueOf(i + 1), df.format(predictPercentResult));
                        }
                    }
                }
                resultList.add(budgetMap);
                resultList.add(predictMap);
                resultList.add(actualMap);
                resultList.add(budgetPercentMap);
                resultList.add(predictPercentMap);
            }
        }
        return resultList;
    }

    @Override
    public List<Map> getPersonalWeeklyList(String personNames) {
        List<String> nameList = new ArrayList<>();
        List<Map> resultList = new ArrayList<>();
        List<String> nameListFromDB = alpWeeklyMapper.getAllXsName();
        if(StringUtils.isNotEmpty(personNames)) {
            String[] personNameList = personNames.split(",");
            for (String pn : personNameList) {
                List searchedList = CollectionUtils.search(pn, nameListFromDB);
                nameList.addAll(searchedList);
            }
        }
        if(nameList.size() > 0){
            for(String name: nameList){
                List<Map> list = alpWeeklyMapper.getPersonalWeeklyList(name);
                Map budgetMap = new HashMap<>();
                budgetMap.put("type","预算");
                budgetMap.put("name",name);
                Map predictMap = new HashMap<>();
                predictMap.put("type","预测");
                predictMap.put("name",name);
                Map actualMap = new HashMap<>();
                actualMap.put("type","结果");
                actualMap.put("name",name);
                Map budgetPercentMap = new HashMap<>();
                budgetPercentMap.put("type","预算准确度");
                budgetPercentMap.put("name",name);
                Map predictPercentMap = new HashMap<>();
                predictPercentMap.put("type","预测准确度");
                predictPercentMap.put("name",name);
                //2020-3-13添加，每类统计都添加合计列
                BigDecimal totalBudget = new BigDecimal(0);
                BigDecimal totalPredict = new BigDecimal(0);
                BigDecimal totalActual = new BigDecimal(0);
                DecimalFormat df = new DecimalFormat("0.00%");
                for(int i = 0; i <= list.size(); i++) {
                    if (i < list.size()) {
                        Map map = list.get(i);
                        //计算预测准确率
                        BigDecimal bMoney = (BigDecimal)map.get("budget_money");
                        BigDecimal pMoney = (BigDecimal)map.get("predict_money");
                        BigDecimal aMoney = (BigDecimal)map.get("actual_money");
                        String budgetPercent;
                        String predictPercent;
                        if(bMoney.compareTo(BigDecimal.ZERO) == 0) {
                            budgetPercent = "0.00%";
                        } else {
                            BigDecimal budgetPercentResult = aMoney.divide(bMoney,4,BigDecimal.ROUND_HALF_UP);
                            budgetPercent = df.format(budgetPercentResult);
                        }
                        if(pMoney.compareTo(BigDecimal.ZERO) == 0) {
                            predictPercent = "0.00%";
                        } else {
                            BigDecimal predictPercentResult = aMoney.divide(pMoney,4,BigDecimal.ROUND_HALF_UP);
                            predictPercent = df.format(predictPercentResult);
                        }
                        budgetMap.put(String.valueOf(i+1), map.get("budget_money"));
                        predictMap.put(String.valueOf(i+1), map.get("predict_money"));
                        actualMap.put(String.valueOf(i+1), map.get("actual_money"));
                        budgetPercentMap.put(String.valueOf(i+1), budgetPercent);
                        predictPercentMap.put(String.valueOf(i+1), predictPercent);
                        //2020-3-13新加合计模块
                        totalBudget = totalBudget.add(bMoney);
                        totalActual = totalActual.add(aMoney);
                        int week = DateUtils.getWeekOfYearByF(new Date(),5);
                        if (i < week - 1) {
                            totalPredict = totalPredict.add(aMoney);
                        }else{
                            totalPredict = totalPredict.add(pMoney);
                        }
                    } else {
                        budgetMap.put(String.valueOf(i + 1), totalBudget);
                        predictMap.put(String.valueOf(i + 1), totalPredict);
                        actualMap.put(String.valueOf(i + 1), totalActual);
                        if (totalBudget.compareTo(BigDecimal.ZERO) == 0) {
                            budgetPercentMap.put(String.valueOf(i + 1), "0.00%");
                        } else {
                            BigDecimal budgetPercentResult = totalActual.divide(totalBudget, 4, BigDecimal.ROUND_HALF_UP);
                            budgetPercentMap.put(String.valueOf(i + 1), df.format(budgetPercentResult));
                        }
                        if (totalPredict.compareTo(BigDecimal.ZERO) == 0) {
                            predictPercentMap.put(String.valueOf(i + 1), "0.00%");
                        } else {
                            BigDecimal predictPercentResult = totalActual.divide(totalPredict, 4, BigDecimal.ROUND_HALF_UP);
                            predictPercentMap.put(String.valueOf(i + 1), df.format(predictPercentResult));
                        }
                    }
                }
                resultList.add(budgetMap);
                resultList.add(predictMap);
                resultList.add(actualMap);
                resultList.add(budgetPercentMap);
                resultList.add(predictPercentMap);
            }
        }
        return resultList;
    }

    @Override
    public List<Map> getContractWeeklyList(String contractName) {
        List<String> nameList = alpWeeklyMapper.getAllContractName();
        List<Map> resultList = new ArrayList<>();
        if(contractName == null || contractName.equals("")){ //前端name传参为空，则说明要全量查询
            nameList = alpWeeklyMapper.getAllContractName();
        } else { //前端name传参不为空，说明要进行匹配
            List searchedList = CollectionUtils.search(contractName,nameList);
            if(searchedList.size() > 0) { //不区分大小写的模糊查询
                nameList.clear();
                for(Object nameObj : searchedList){
                    nameList.add((String)nameObj);
                }
            } else {
                nameList.clear();
            }
        }
        if(nameList.size() > 0){
            for(String name: nameList){
                List<Map> list = alpWeeklyMapper.getContractWeeklyList(name);
                Map budgetMap = new HashMap<>();
                budgetMap.put("type","预算");
                budgetMap.put("name",name);
                Map predictMap = new HashMap<>();
                predictMap.put("type","预测");
                predictMap.put("name",name);
                Map actualMap = new HashMap<>();
                actualMap.put("type","结果");
                actualMap.put("name",name);
                Map percentMap = new HashMap<>();
                percentMap.put("type","预测准确度");
                percentMap.put("name",name);
                for(int i = 0; i < list.size(); i++) {
                    Map map = list.get(i);
                    //计算预测准确率
                    BigDecimal pMoney = (BigDecimal)map.get("predict_money");
                    BigDecimal aMoney = (BigDecimal)map.get("actual_money");
                    String percent;
                    int c = aMoney.compareTo(BigDecimal.ZERO);
                    if(c == 0) {
                        percent = "0.00%";
                    } else {
                        DecimalFormat df = new DecimalFormat("0.00%");
                        BigDecimal result5 = pMoney.divide(aMoney,4,BigDecimal.ROUND_HALF_UP);
                        percent = df.format(result5);
                    }
                    budgetMap.put(String.valueOf(i+1), map.get("budget_money"));
                    predictMap.put(String.valueOf(i+1), map.get("predict_money"));
                    actualMap.put(String.valueOf(i+1), map.get("actual_money"));
                    percentMap.put(String.valueOf(i+1), percent);
                }
                resultList.add(budgetMap);
                resultList.add(predictMap);
                resultList.add(actualMap);
                resultList.add(percentMap);
            }
        }
        return resultList;
    }

    @Override
    public List<Map> getWeeklyPivotTable(PivotRequest pivotRequest) {
        String[] startAndEndDate = DateUtils.getStartAndEndByWeek(pivotRequest.getWeek(), 5);
        List<Map> list = new ArrayList<>();
        if(!StringUtils.isEmpty(pivotRequest.getName())){
            if(pivotRequest.getLevel().equals("部门级")){
                pivotRequest.setDeptName(pivotRequest.getName());
            }
            if(pivotRequest.getLevel().equals("个人级")){
                pivotRequest.setPersonName(pivotRequest.getName());
            }
//            if(pivotRequest.getLevel().equals("项目级")){
//                pivotRequest.setPersonName(pivotRequest.getName());
//            }
        }
        if(startAndEndDate != null){
            pivotRequest.setStartTime(startAndEndDate[0]);
            pivotRequest.setEndTime(startAndEndDate[1]);
        }
        if(pivotRequest.getType().equals("预算")){
            list = alpWeeklyMapper.getWeeklyBudgetPivotTable(pivotRequest);
        }
        if(pivotRequest.getType().equals("预测")){
            list = alpWeeklyMapper.getWeeklyPredictPivotTable(pivotRequest);
        }
        if(pivotRequest.getType().equals("实际")){
            list = alpWeeklyMapper.getWeeklyActualPivotTable(pivotRequest);
        }
        return list;
    }


    /**
     * 查询项目列表，统计周记录，当前日期前为实际回款数，当前日期后为预测回款数
     * @param alpContractDetail
     * @return
     */
    @Override
    public List<Map> getContractWeekly(AlpContractDetail alpContractDetail, String quarter, Integer weekNo) {
        Map map = new HashMap();
        map.put("contractNo", alpContractDetail.getContractNo());
        map.put("contractName", alpContractDetail.getContractName());
        map.put("xsPrincipalName", alpContractDetail.getXsPrincipalName());
        map.put("xsDepartment", alpContractDetail.getXsDepartment());
        map.put("weekNo", weekNo);
        List<Map> alpContractDetails = alpContractDetailMapper.selectWeeklyContractDetailList(map);
        Calendar c = Calendar.getInstance();
        String year = String.valueOf(c.get(Calendar.YEAR));
        String startTime,endTime;
        Integer startWeek,endWeek;
        switch (quarter) {
            case "1" :
                startTime = year + "-01-01";
                endTime = year + "-03-31";
                break;
            case "2" :
                startTime = year + "-04-01";
                endTime = year + "-06-30";
                break;
            case "3" :
                startTime = year + "-07-01";
                endTime = year + "-09-30";
                break;
            case "4" :
                startTime = year + "-10-01";
                endTime = year + "-12-31";
                break;
            default:
                startTime = year + "-01-01";
                endTime = year + "-12-31";
        }
        startWeek = DateUtils.getWeekOfYearByF(DateUtils.parseDate(startTime), 5);
        endWeek = DateUtils.getWeekOfYearByF(DateUtils.parseDate(endTime), 5);

        Map requestMap = new HashMap();
        requestMap.put("startTime", startTime);
        requestMap.put("endTime", endTime);
        requestMap.put("startWeek", startWeek);
        requestMap.put("endWeek", endWeek);
        List<Map> resultList = new ArrayList<>();
        for(Map a : alpContractDetails){
            requestMap.put("contractId", a.get("contractId"));
            List<Map> weeklyMapList = alpWeeklyMapper.getContractWeekly(requestMap);
            Map responseMap = new HashMap();
            responseMap.put("contractId", a.get("contractId"));
            responseMap.put("contractNo", a.get("contractNo"));
            responseMap.put("contractName", a.get("contractName"));
            responseMap.put("xsPrincipalName", a.get("xsPrincipalName"));
            responseMap.put("partyAName", a.get("partyAName"));
            responseMap.put("balanceSince2020", a.get("balanceSince2020"));
            for(int i = 0; i < weeklyMapList.size(); i++){
                BigDecimal weeklyMoney = (BigDecimal)weeklyMapList.get(i).get("money");
                BigDecimal tenThousand = new BigDecimal(10000);
                responseMap.put("W" + weeklyMapList.get(i).get("weekly"), weeklyMoney.divide(tenThousand, 2, BigDecimal.ROUND_HALF_UP));
            }
            resultList.add(responseMap);
        }
        return resultList;
    }

    @Override
    public int getWeeklyCount(AlpContractDetail alpContractDetail, Integer weekNo) {
        Map map = new HashMap();
        map.put("contractNo", alpContractDetail.getContractNo());
        map.put("contractName", alpContractDetail.getContractName());
        map.put("xsPrincipalName", alpContractDetail.getXsPrincipalName());
        map.put("xsDepartment", alpContractDetail.getXsDepartment());
        map.put("weekNo", weekNo);
        return alpContractDetailMapper.getWeeklyCount(map);
    }
}
